(function () {
    // ['子鼠','丑牛','寅虎','卯兔','辰龙','巳蛇','午马','未羊','申猴','酉鸡','戌狗','亥猪']

    /**
     * 生肖构造函数，默认参数是当前日期
     * @param {Number} year 年
     * @param {Number} month 月
     * @param {Number} day 日
     */
    function Zodiac(year, month, day) {
        let date = new Date();
        this.year = parseInt(year) || date.getFullYear();
        this.month = parseInt(month) || (date.getMonth() + 1);
        this.day = parseInt(day)  || date.getDate();
        this.config = {
            zodiac:['鼠','牛','虎','兔','龙','蛇','马','羊','猴','鸡','狗','猪'],
            zodiacLetter:['shu', 'niu', 'hu', 'tu', 'long', 'she', 'ma', 'yang', 'hou', 'ji', 'gou', 'zhu'],
            jixiongZodiac:{
                ji:['兔','龙','蛇','马','羊','鸡'],
                xiong:['鼠','牛','虎','猴','狗','猪']
            },
            jiayeZodiac:{
                jia:['牛','马','羊','鸡','狗','猪'],
                ye:['鼠','虎','兔','龙','蛇','猴']
            },
            tiandiZodiac:{
                tian:['兔','马','猴','猪','牛','龙',],
                di:['蛇','羊','鸡','狗','鼠','虎']
            },
            yinyangZodiac:{
                yin:['兔','马','猴','猪','牛','龙',],
                yang:['蛇','羊','鸡','狗','鼠','虎']
            },
            danshuangZodiac:{
                dan:['鼠','龙','马','蛇','鸡','猪'],
                shuang:['虎','猴','狗','兔','羊','牛']
            },
            heibaiZodiac:{ //黑白肖
                hei:['兔','龙','蛇','马','羊','猴'],
                bai:['鼠','牛','虎','鸡','狗','猪']
            },
            nannvZodiac:{ //男女肖
                nan:['鼠','牛','虎','龙','马','猴','狗'],
                nv:['兔','蛇','羊','鸡','猴','猪']
            },
            yanseZodiac:{ // 红蓝绿肖
                hong:['鸡','马','兔','鼠'],
                lan:['猪','猴','蛇','虎'],
                lv:['狗','羊','龙','牛']
            },
            jijieZodiac:{ // 春夏秋冬肖
                chun:['虎','兔','龙'],
                xia:['蛇','马','羊'],
                qiu:['猴','鸡','狗'],
                dong:['鼠','牛','猪'],
            },
            fangxiangZodiac:{ // 东南西北肖
                dong:['虎','兔','龙'],
                nan:['蛇','马','羊'],
                xi:['猴','鸡','狗'],
                bei:['鼠','牛','猪']
            },
            qqshZodiac:{ // 琴棋书画
                qin:['兔','蛇','鸡'],
                qi:['鼠','牛','狗'],
                shu:['虎','龙','马'],
                hua:['羊','猴','猪'],
            },
            wuxingZodiac:{ // 金木水火土
                jin:[5,6,19,20,27,28,35,36,49],
                mu:[1,2,9,10,17,18,31,32,39,40,47,48],
                shui:[7,8,15,16,23,24,37,38,45,46],
                huo:[3,4,11,12,25,26,33,34,41,42],
                tu:[13,14,21,22,29,30,43,44]
            },
            boZodiac:{ // 红蓝绿波段
                hong:[1,2,7,8,12,13,18,19,23,24,29,30,34,35,40,45,46],
                lan:[3,4,9,10,14,15,20,25,26,31,36,37,41,42,47,48],
                lv:[5,6,11,16,17,21,22,27,28,32,33,38,39,43,44,49],
            },
            heZodiac:{ //合单双
                dan:[1,3,5,7,9,10,12,14,16,18,21,23,25,27,29,30,32,34,36,38,41,43,45,47,49],
                shuang:[2,4,6,8,11,13,15,17,19,20,22,24,26,28,31,33,35,37,39,40,42,44,46,48],
            },
            daxiaoZodiac:{ //大小数
                da:[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24],
                xiao:[25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49],
            },
            attrNames:{
                bo:{hong:'红', lan:'蓝',lv:'绿'},
                daxiao:{da:'大数', xiao:'小数'},
                he:{dan:'合单', shuang:'合双'},
                wuxing:{jin:'金', mu:'木',shui:'水', huo:'火', tu:'土'},
                jixiong: {ji:'吉', xiong:'凶'},
                jiaye:{jia:'家肖', ye:'野肖'},
                tiandi:{tian:'天肖', di:'地肖'},
                yinyang:{yin:'阴肖', yang:'阳肖'},
                danshuang:{dan:'单笔', shuang:'双笔'},
                heibai:{hei:'黑肖', bai:'白肖'},
                nannv:{nan:'男肖', nv:'女肖'},
                yanse:{hong:'红肖', lan:'蓝肖', lv:'绿肖'},
                jijie:{chun:'春肖', xia:'夏肖', qiu:'秋肖',dong:'冬肖'},
                fangxiang:{dong:'东肖', xi:'西肖', nan:'南肖', bei:'北肖'},
                qqsh:{qin:'东肖', qi:'西肖', shu:'南肖', hua:'北肖'},
                shengxiao:['鼠','牛','虎','兔','龙','蛇','马','羊','猴','鸡','狗','猪']
            },
            codeConfig:{}
        };
    }

    Zodiac.constructor = Zodiac;


    /**
     * 获取C值
     * @return {Number} C
     */
    Zodiac.prototype.getC = function(){
        let _year = Math.floor(this.year/100)+1, C;
        switch(_year){
            case 20:
                C = 4.6295;
                break;
            case 21:
                C = 3.87;
                break;
            case 22:
                C = 4.15;
                break;
            default:
                C = 3.87;
        }
        return C;
    };

    /**
     * 获取立春日 一般都在2月
     * @return {Number} springDay
     */
    Zodiac.prototype.getSpringDay = function(){
        let Y = this.year%100, D = 0.2422,
            C = this.getC(), L = (Y-1)/4, springDay = 0;
        return Math.floor(Y*D+C)-Math.floor((Y-1)/4);
    };

    /**
     * 获取生肖
     * @return {Object} myZodiac
     */
    Zodiac.prototype.getYearZodiac = function(){
        let year = this.year, month = this.month, day = this.day,
            zodiac = this.config.zodiac,
            zodiacLetter = this.config.zodiacLetter,
            myPos = (year-1900)%12, myZodiac = zodiac[myPos], myLetter = zodiacLetter[myPos], springDay = this.getSpringDay();

        switch(month){
            case 1:
                let _myPos = myPos-1;
                if(_myPos<0){
                    _myPos = 11;
                }
                myZodiac = zodiac[_myPos];
                myLetter = zodiacLetter[_myPos];
                myPos = _myPos;
                console.log(2)
                break;
            case 2:
                if(day < springDay){
                    let _myPos = myPos-1;
                    if(_myPos<0){
                        _myPos = 11;
                    }
                    myZodiac = zodiac[_myPos];
                    myLetter = zodiacLetter[_myPos]
                    myPos = _myPos;
                    console.log(1)
                }
                break;
        }
        return {pos:myPos, name:myZodiac, letter:myLetter};
    };



    /**
     * 获取红蓝绿波段名称
     * @param code
     * @returns {string}
     */
    Zodiac.prototype.getBoName = function(code) {
        let names = {hong:'红', lan:'蓝',lv:'绿'};
        for (let index in this.config.boZodiac) {
            if (this.config.boZodiac[index].indexOf(code) > -1){
                return names[index] + '波';
            }
        }
        return '';
    };

    /**
     * 大数、小数名称
     * @param code
     * @returns {string}
     */
    Zodiac.prototype.getDaxiaoName = function(code) {
        let names = {da:'大数', xiao:'小数'};
        for (let index in this.config.daxiaoZodiac) {
            if (this.config.daxiaoZodiac[index].indexOf(code) > -1) {
                return names[index];
            }
        }
        return '';
    };

    /**
     * 合单、合双名称
     * @param code
     * @returns {string}
     */
    Zodiac.prototype.getHeName = function(code) {
        let names = {dan:'合单', shuang:'合双'};
        for (let index in this.config.heZodiac) {
            if (this.config.heZodiac[index].indexOf(code) > -1) {
                return names[index];
            }
        }
        return '';
    };

    /**
     * 根据code获取五行名称
     * @param code
     * @returns {string}
     */
    Zodiac.prototype.getWuxingName = function(code) {
        let names = {jin:'金', mu:'木',shui:'水', huo:'火', tu:'土'};
        for (let index in this.config.wuxingZodiac) {
            if (this.config.wuxingZodiac[index].indexOf(code) > -1) {
                return names[index];
            }
        }
        return '';
    };

    /**
     * 获取吉凶肖
     * @param zodiacName
     * @returns {string}
     */
    Zodiac.prototype.getJixiongName = function(zodiacName) {
        let names = {ji:'吉', xiong:'凶'};
        if (zodiacName)
        for (let index in this.config.jixiongZodiac) {
            if (this.config.jixiongZodiac[index].indexOf(zodiacName) > -1) {
                return names[index] + '肖';
            }
        }
        return '';
    };

    /**
     * 获取家野肖
     * @param zodiacName
     * @returns {string}
     */
    Zodiac.prototype.getJiayeName = function(zodiacName) {
        let names = {jia:'家肖', ye:'野肖'};

        if (typeof zodiacName === 'number') {
            zodiacName = '';
        }
        for (let index in this.config.jiayeZodiac) {
            if (this.config.jiayeZodiac[index].indexOf(zodiacName) > -1) {
                return names[index];
            }
        }
        return '';
    };

    /**
     * 获取家野肖
     * @param zodiacName
     * @returns {string}
     */
    Zodiac.prototype.getTiandiName = function(zodiacName) {
        let names = {tian:'天肖', di:'地肖'};
        for (let index in this.config.tiandiZodiac) {
            if (this.config.tiandiZodiac[index].indexOf(zodiacName) > -1) {
                return names[index];
            }
        }
        return '';
    };

    /**
     * 获取阴阳肖
     * @param zodiacName
     * @returns {string}
     */
    Zodiac.prototype.getYinyangName = function(zodiacName) {
        let names = {yin:'阴肖', yang:'阳肖'};
        for (let index in this.config.yinyangZodiac) {
            if (this.config.yinyangZodiac[index].indexOf(zodiacName) > -1) {
                return names[index];
            }
        }
        return '';
    };

    /**
     * 获取单双笔
     * @param zodiacName
     * @returns {string}
     */
    Zodiac.prototype.getDanshuangName = function(zodiacName) {
        let names = {dan:'单笔', shuang:'双笔'};
        for (let index in this.config.danshuangZodiac) {
            if (this.config.danshuangZodiac[index].indexOf(zodiacName) > -1) {
                return names[index];
            }
        }
        return '';
    };

    /**
     * 获取黑白肖
     * @param zodiacName
     * @returns {string}
     */
    Zodiac.prototype.getHeibaiName = function(zodiacName) {
        let names = {hei:'黑肖', bai:'白肖'};
        for (let index in this.config.heibaiZodiac) {
            if (this.config.heibaiZodiac[index].indexOf(zodiacName) > -1) {
                return names[index];
            }
        }
        return '';
    };

    /**
     * 获取男女肖
     * @param zodiacName
     * @returns {string}
     */
    Zodiac.prototype.getNannvName = function(zodiacName) {
        let names = {nan:'男肖', nv:'女肖'};
        for (let index in this.config.nannvZodiac) {
            if (this.config.nannvZodiac[index].indexOf(zodiacName) > -1) {
                return names[index];
            }
        }
        return '';
    };

    /**
     * 获取红蓝绿肖
     * @param zodiacName
     * @returns {string}
     */
    Zodiac.prototype.getYanseName = function(zodiacName) {
        let names = {hong:'红肖', lan:'蓝肖', lv:'绿肖'};
        for (let index in this.config.yanseZodiac) {
            if (this.config.yanseZodiac[index].indexOf(zodiacName) > -1) {
                return names[index];
            }
        }
        return '';
    };

    /**
     * 获取春夏秋冬肖
     * @param zodiacName
     * @returns {string}
     */
    Zodiac.prototype.getJijieName = function(zodiacName) {
        let names = {chun:'春肖', xia:'夏肖', qiu:'秋肖',dong:'冬肖'};
        for (let index in this.config.jijieZodiac) {
            if (this.config.jijieZodiac[index].indexOf(zodiacName) > -1) {
                return names[index];
            }
        }
        return '';
    };

    /**
     * 获取东西南北肖
     * @param zodiacName
     * @returns {string}
     */
    Zodiac.prototype.getFangxiangName = function(zodiacName) {
        let names = {dong:'东肖', xi:'西肖', nan:'南肖', bei:'北肖'};
        for (let index in this.config.fangxiangZodiac) {
            if (this.config.fangxiangZodiac[index].indexOf(zodiacName) > -1) {
                return names[index];
            }
        }
        return '';
    };

    /**
     * 获取琴棋书画肖
     * @param zodiacName
     * @returns {string}
     */
    Zodiac.prototype.getQqshName = function(zodiacName) {
        let names = {qin:'琴肖', qi:'棋肖', shu:'书肖', hua:'画肖'};
        for (let index in this.config.qqshZodiac) {
            if (this.config.qqshZodiac[index].indexOf(zodiacName) > -1) {
                return names[index];
            }
        }
        return '';
    };

    /**
     * 根据 code 获取生肖信息
     * @param code
     * @returns {{pos: number, name: string, letter: string, wuxing: string, jixiong: string, jiaye: string, tiandi: string, yinyang: string, danshuang: string, heibai: string, nannv: string, yanse: string, jijie: string, fangxiang: string, qqsh: string, bo: string, he: string, daxiao: string}}
     */
    Zodiac.prototype.getCodeZodiac = function(code) {
        let myZodiac = this.getYearZodiac(), pos = myZodiac.pos+1;
        let myPos = Math.abs(11 - (code % 12)) + 1;
        myPos = myPos === 12 ? 0 : myPos;
        let name = this.config.zodiac[myPos];
        return {
            pos:myPos,
            name:name,
            letter:this.config.zodiacLetter[myPos],
            wuxing:this.getWuxingName(code),
            jixiong:this.getJixiongName(name),
            jiaye:this.getJiayeName(name),
            tiandi:this.getTiandiName(name),
            yinyang:this.getYinyangName(name),
            danshuang:this.getDanshuangName(name),
            heibai:this.getHeibaiName(name),
            nannv:this.getNannvName(name),
            yanse:this.getYanseName(name),
            jijie:this.getJijieName(name),
            fangxiang:this.getFangxiangName(name),
            qqsh:this.getQqshName(name),
            bo:this.getBoName(code),
            he:this.getHeName(code),
            daxiao:this.getDaxiaoName(code),
            code:code
        };
    };


    Zodiac.prototype.getCodeByZodiac = function(zodiacIndex) {
        zodiacIndex = parseInt(zodiacIndex);
        let myZodiac = this.getYearZodiac(), pos = myZodiac.pos + 1, code = Math.abs(12-zodiacIndex), codes = [];
        for (let i = 0; i < 4; i++) {
            codes.push(code + i * 12);
        }

        if (zodiacIndex === myZodiac.pos) {
            codes.push(49);
        }

        return codes;
    };


    Zodiac.prototype.getCodeConfig = function() {
        let allKeys = ['jixiongZodiac','jiayeZodiac','tiandiZodiac','yinyangZodiac','danshuangZodiac','heibaiZodiac','nannvZodiac','yanseZodiac','jijieZodiac','fangxiangZodiac','qqshZodiac'];
        let codeConfig = {};

        let zodiacCode = [];
        for (let index in this.config.zodiac) {
            zodiacCode.push(this.getCodeByZodiac(index));
        }

        for (let key in allKeys) {
            codeConfig[allKeys[key].replace('Zodiac', '')] = this.getCodeByConfigKey(allKeys[key], zodiacCode);
        }

        codeConfig.he = this.config.heZodiac;
        codeConfig.bo = this.config.boZodiac;
        codeConfig.daxiao = this.config.daxiaoZodiac;
        codeConfig.wuxing = this.config.wuxingZodiac;
        codeConfig.shengxiao = zodiacCode;
        return codeConfig;
    };


    Zodiac.prototype.getCodeByConfigKey = function(key, zodiacCode) {
        if (!zodiacCode) {
            zodiacCode = [];
            for (let index in this.config.zodiac) {
                zodiacCode.push(this.getCodeByZodiac(index));
            }
        }

        let config = this.config[key], codes = {};
        for (let index in config) {
            codes[index] = [];
            for (let i in config[index]) {
                let code = zodiacCode[this.config.zodiac.indexOf(config[index][i])];
                codes[index].push.apply(codes[index], code);
            }
        }
        return codes;
    };


    window.zodiac = new Zodiac();
})();




